package com.xujie.sportsmeeting.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.sportsmeeting.common.exception.BusinessException;
import com.xujie.sportsmeeting.common.result.ResultCode;
import com.xujie.sportsmeeting.controller.UserController.RoleVO;
import com.xujie.sportsmeeting.dto.UserQueryDTO;
import com.xujie.sportsmeeting.entity.SysRole;
import com.xujie.sportsmeeting.entity.SysUser;
import com.xujie.sportsmeeting.entity.SysUserRole;
import com.xujie.sportsmeeting.mapper.SysRoleMapper;
import com.xujie.sportsmeeting.mapper.SysUserMapper;
import com.xujie.sportsmeeting.mapper.SysUserRoleMapper;
import com.xujie.sportsmeeting.service.SysUserService;
import com.xujie.sportsmeeting.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    private final SysUserRoleMapper sysUserRoleMapper;
    private final SysRoleMapper sysRoleMapper;

    @Override
    public SysUser findByUsername(String username) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, username)
               .eq(SysUser::getStatus, 1);
        return getOne(wrapper);
    }

    @Override
    public String login(String username, String password) {
        // 查询用户
        SysUser user = findByUsername(username);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException(ResultCode.USER_DISABLED);
        }

        // 验证密码
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException(ResultCode.PASSWORD_ERROR);
        }

        // 更新最后登录时间
        updateLastLoginTime(user.getId());

        // 生成JWT token
        return jwtUtil.generateToken(username);
    }

    @Override
    public boolean register(SysUser user) {
        // 检查用户名是否存在
        SysUser existUser = findByUsername(user.getUsername());
        if (existUser != null) {
            throw new BusinessException(ResultCode.USERNAME_EXISTS);
        }

        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setStatus(1); // 默认启用

        return save(user);
    }

    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        SysUser user = getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 验证原密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new BusinessException(ResultCode.OLD_PASSWORD_ERROR);
        }

        // 更新新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }

    @Override
    public List<String> findRolesByUserId(Long userId) {
        // 1. 查询用户角色关联
        LambdaQueryWrapper<SysUserRole> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleWrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoles = sysUserRoleMapper.selectList(userRoleWrapper);
        
        if (userRoles.isEmpty()) {
            return List.of();
        }
        
        // 2. 获取角色ID列表
        List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());
        
        // 3. 查询角色信息
        LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.in(SysRole::getId, roleIds)
                   .eq(SysRole::getStatus, 1);
        List<SysRole> roles = sysRoleMapper.selectList(roleWrapper);
        
        return roles.stream()
                .map(SysRole::getRoleCode)
                .collect(Collectors.toList());
    }

    @Override
    public List<String> findPermissionsByUserId(Long userId) {
        // 简化处理：根据角色返回基础权限
        List<String> roles = findRolesByUserId(userId);
        return roles.stream()
                .map(role -> {
                    switch (role) {
                        case "ADMIN":
                            return List.of("system:user", "athlete", "judge", "event", "score", "statistics", "notice");
                        case "JUDGE":
                            return List.of("athlete", "judge", "score", "notice");
                        case "SCORER":
                            return List.of("score");
                        case "ATHLETE":
                            return List.of("athlete", "event", "score", "notice");
                        default:
                            return List.of("notice");
                    }
                })
                .flatMap(List::stream)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public boolean updateLastLoginTime(Long userId) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setLastLoginTime(LocalDateTime.now());
        return updateById(user);
    }

    @Override
    public IPage<SysUser> getUserPage(IPage<SysUser> page, UserQueryDTO queryDTO) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        wrapper.like(StringUtils.hasText(queryDTO.getUsername()), SysUser::getUsername, queryDTO.getUsername())
               .like(StringUtils.hasText(queryDTO.getRealName()), SysUser::getRealName, queryDTO.getRealName())
               .like(StringUtils.hasText(queryDTO.getDepartment()), SysUser::getDepartment, queryDTO.getDepartment())
               .like(StringUtils.hasText(queryDTO.getPhone()), SysUser::getPhone, queryDTO.getPhone())
               .like(StringUtils.hasText(queryDTO.getEmail()), SysUser::getEmail, queryDTO.getEmail())
               .eq(queryDTO.getStatus() != null, SysUser::getStatus, queryDTO.getStatus())
               .orderByDesc(SysUser::getCreateTime);
        
        return page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean createUser(SysUser user) {
        // 检查用户名是否存在
        SysUser existUser = findByUsername(user.getUsername());
        if (existUser != null) {
            throw new BusinessException(ResultCode.USERNAME_EXISTS);
        }

        // 加密密码
        if (StringUtils.hasText(user.getPassword())) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        } else {
            // 设置默认密码
            user.setPassword(passwordEncoder.encode("123456"));
        }
        
        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1);
        }

        return save(user);
    }

    @Override
    @Transactional
    public boolean updateUser(SysUser user) {
        SysUser existUser = getById(user.getId());
        if (existUser == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 如果更新了用户名，检查是否重复
        if (!existUser.getUsername().equals(user.getUsername())) {
            SysUser duplicateUser = findByUsername(user.getUsername());
            if (duplicateUser != null && !duplicateUser.getId().equals(user.getId())) {
                throw new BusinessException(ResultCode.USERNAME_EXISTS);
            }
        }

        // 不更新密码和创建时间
        user.setPassword(null);
        user.setCreateTime(null);
        
        return updateById(user);
    }

    @Override
    public boolean resetPassword(Long userId, String newPassword) {
        SysUser user = getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }

    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setStatus(status);
        return updateById(user);
    }

    @Override
    public List<RoleVO> getAllRoles() {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getStatus, 1)
               .orderByDesc(SysRole::getCreateTime);
        
        List<SysRole> roles = sysRoleMapper.selectList(wrapper);
        return roles.stream().map(role -> {
            RoleVO vo = new RoleVO();
            vo.setId(role.getId());
            vo.setRoleName(role.getRoleName());
            vo.setRoleCode(role.getRoleCode());
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean assignUserRoles(Long userId, List<Long> roleIds) {
        // 删除原有角色
        LambdaQueryWrapper<SysUserRole> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysUserRole::getUserId, userId);
        sysUserRoleMapper.delete(deleteWrapper);

        // 分配新角色
        if (roleIds != null && !roleIds.isEmpty()) {
            List<SysUserRole> userRoles = roleIds.stream().map(roleId -> {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                return userRole;
            }).collect(Collectors.toList());

            for (SysUserRole userRole : userRoles) {
                sysUserRoleMapper.insert(userRole);
            }
        }

        return true;
    }
}
